package com.fhzz.service;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,timeout=5)
@Service
public class WorkflowService {
	
	@Autowired
	private RepositoryService rep;
	
	@Autowired
	private RuntimeService runservice;
	
	@Autowired
	private TaskService taskservice;
	
	@Autowired
	private HistoryService histiryservice;
	
	
	
	public Deployment createDeployment(String name,ZipInputStream zipInputStream) {
		Deployment deployment = rep.createDeployment()
				.addZipInputStream(zipInputStream)
				.name(name).deploy();
		return deployment;
	}
	
	
	
	
	/**
	 * 删除部署的流程
	 * @param deployid
	 */
	public void deleteDeploy(String deployId) {
		rep.deleteDeployment(deployId, true);
	}
	
	
	/**
	 * 开始流程实例
	 * @param key
	 * @param businesskey
	 * @param variables
	 * @return
	 */
	public ProcessInstance startProcessInstanceByKey(String key,String businesskey,
			Map<String, Object> variables) {
		ProcessInstance instance = runservice.
				startProcessInstanceByKey(key,businesskey,variables);
		return instance;
	}
	
	/**
	 * 查询参与的流程
	 * @param key
	 * @param userId
	 * @param firstrow
	 * @param rowCount
	 * @return
	 */
	public List<ProcessInstance> getUserProcessInstance(String key,String userId,
			int firstrow,int rowCount
			){
		ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
		List<ProcessInstance> list = query.processDefinitionKey(key).
				involvedUser(userId).listPage(firstrow, rowCount);
		return list;
	}
	
	/**
	 * 参与的流程数量
	 * @param key
	 * @param userId
	 * @return
	 */
	public int getUserProcessInstanceCount(String key,String userId){
		ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
		List<ProcessInstance> list = query.processDefinitionKey(key).
				involvedUser(userId).list();
		return list.size();
	}
	
	/**
	 * 获取HistoricActivityInstance
	 * @param executionid
	 * @return
	 */
	public List<HistoricActivityInstance> getHistoricActivityInstance(String executionid){
		// 获得历史活动记录实体（通过启动时间正序排序，不然有的线可以绘制不出来）
		List<HistoricActivityInstance> historicActivityInstances = histiryservice.createHistoricActivityInstanceQuery()
				.executionId(executionid).orderByHistoricActivityInstanceStartTime().asc().list();
		return historicActivityInstances;
	}
	
	/**
	 * 查询我发起的流程
	 * @return
	 */
	public List<HistoricProcessInstance> getHistoricProcessInstanceList(String userId,String key
			,int firstRow,int rowCount){
		List<HistoricProcessInstance> list = histiryservice.createHistoricProcessInstanceQuery()
				.startedBy(userId).processDefinitionKey(key).listPage(firstRow, rowCount);
		return list;
	}
	
	/**
	 * 查询我发起的流程数
	 * @return
	 */
	public int getHistoricProcessInstanceCount(String userId,String key){
		List<HistoricProcessInstance> list = histiryservice.createHistoricProcessInstanceQuery()
				.startedBy(userId).processDefinitionKey(key).list();
		return list.size();
	}
	
	/**
	 * 根据groupName分页获取任务列表
	 * @param groupName
	 * @return
	 */
	public List<Task> getTaskCandidateGroup(String groupName,int firstRow,int rowCount){
		List<Task> tasks = taskservice.createTaskQuery()
				.taskCandidateGroup(groupName)
				.listPage(firstRow, rowCount);
		return tasks;
	}
	
	/**
	 * 根据assinged和groupname分页获取任务列表
	 * @param userId
	 * @param groupName
	 * @return
	 */
	public List<Task> getTaskCandidateOrAssigned(String userId,String groupName,int firstRow,int rowCount ){
		List<Task> tasks=taskservice.createTaskQuery().
				taskCandidateOrAssigned(userId)
				.taskName(groupName).listPage(firstRow, rowCount);
		return tasks;
	}
	
	/**
	 * 根据assinged和groupname分页获取任务数量
	 * @param userId
	 * @param groupName
	 * @param firstRow
	 * @param rowCount
	 * @return
	 */
	public int getTaskCandidateOrAssignedCount(String userId,String groupName) {
		List<Task> tasks=taskservice.createTaskQuery().
				taskCandidateOrAssigned(userId)
				.taskName(groupName).list();
		return tasks.size();
	}
	
	/**
	 * 根据组名获取任务数量
	 * @param groupName
	 * @return
	 */
	public int getTaskCandidateGroupCount(String groupName) {
		List<Task> tasks=taskservice.createTaskQuery().taskCandidateGroup(groupName).list();
		return tasks.size();
	}
	
	/**
	 * 根据id获取ProcessInstance
	 * @param instanceId
	 * @return
	 */
	public ProcessInstance getInstanceById(String instanceId) {
		ProcessInstance ins=runservice.createProcessInstanceQuery()
				.processInstanceId(instanceId).singleResult();
		return ins;
	}
	
	/**
	 * 完成任务
	 * @param userId
	 * @param variables
	 */
	public void completeTask(String userId,String taskId,Map<String,Object> variables) {
		taskservice.claim(taskId, userId);
		taskservice.complete(taskId, variables);
	}
	
	/**
	 * 完成任务
	 * @param taskId
	 */
	public void completeTask(String taskId) {
		taskservice.complete(taskId);
	}
	
	/**
	 * 完成任务
	 * @param taskId
	 */
	public void completeTask(String taskId,Map<String,Object> variables) {
		taskservice.complete(taskId, variables);
	}
	
	/**
	 * 根据id获取任务
	 * @param taskid
	 * @return
	 */
	public Task getTaskById(String taskid) {
		Task task = taskservice.createTaskQuery()
				.taskId(taskid)
				.singleResult();
		return task;
	}
	
	/**
	 * 根据key和userId获取历史流程
	 * @param key
	 * @param userId
	 * @return
	 */
	public HistoricProcessInstanceQuery getHistoricProcess(String key,String userId) {
		HistoricProcessInstanceQuery processes = histiryservice.createHistoricProcessInstanceQuery()
				.processDefinitionKey(key).startedBy(userId).finished();
		return processes;
	}
	
	/**
	 * 获取流程操作历史
	 * @param instanceid
	 * @return
	 */
	public List<HistoricActivityInstance> getHistoricActivityInstanceById(String instanceId) {
		List<HistoricActivityInstance> list = histiryservice.createHistoricActivityInstanceQuery()
				.processInstanceId(instanceId).orderByHistoricActivityInstanceStartTime().asc().list();
		return list;
	}
	
	/**
	 * 获取流程进展图片流
	 * @param processInstanceId
	 * @return
	 */
	public InputStream getDiagram(String processInstanceId) {
 	    //获得流程实例
 	    ProcessInstance processInstance = runservice.createProcessInstanceQuery()
 	            .processInstanceId(processInstanceId).singleResult();
 	    String processDefinitionId = StringUtils.EMPTY;
 	    if (processInstance == null) {
 	        //查询已经结束的流程实例
 	        HistoricProcessInstance processInstanceHistory =
 	        		histiryservice.createHistoricProcessInstanceQuery()
 	                        .processInstanceId(processInstanceId).singleResult();
 	        if (processInstanceHistory == null) {
 	        	return null;
 	        }else {
 	        	processDefinitionId = processInstanceHistory.getProcessDefinitionId();
 	        }
 	    } else {
 	        processDefinitionId = processInstance.getProcessDefinitionId();
 	    }

 	    //使用宋体
 	    String fontName = "宋体";
 	    //获取BPMN模型对象
 	    BpmnModel model = rep.getBpmnModel(processDefinitionId);
 	    //获取流程实例当前的节点，需要高亮显示
 	    List<String> currentActs = Collections.EMPTY_LIST;
 	    if (processInstance != null)
 	        currentActs = runservice.getActiveActivityIds(processInstance.getId());
 	    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 	    return processEngine.getProcessEngineConfiguration()
 	            .getProcessDiagramGenerator()
 	            .generateDiagram(model, "png", currentActs, new ArrayList<String>(),
 	                    fontName, fontName, fontName, null, 1.0);
 	}
	
	
		
}